//----------------------------------------------------------------------------------------
// @Project Includes
#include "includes.h"

//----------------------------------------------------------------------------------------
// @Local Macro Define in the module

//----------------------------------------------------------------------------------------
// @Local Type defines in the module

//----------------------------------------------------------------------------------------
// @Global Variables define in the module
stc_event_t g_stcEvent;

//----------------------------------------------------------------------------------------
// @Prototypes of functions in the module
static void Srv_Event_PageDelete(uint32_t Page_Address);
static void srv_event_saveRecord(uint8_t *pBuf, uint8_t len);

//========================================================================================

/**
 * @brief  event page delete
 * @param  none
 * @return none
 * @note   none
 */ 
static void Srv_Event_PageDelete(uint32_t Page_Address)
{
    /* Unlocks the FLASH Program Erase Controller */
    FLASH_Unlock();
    /* Erase */
    if (FLASH_COMPL != FLASH_EraseOnePage(Page_Address))
    {
        SYSTEM_DEBUG("Event:<< erase address =0x%0x error !\r\n", Page_Address);
    }
		else
		{
				SYSTEM_DEBUG("Event:<< erase address =0x%0x success !\r\n", Page_Address);
		}

    /* Locks the FLASH Program Erase Controller */
    FLASH_Lock();	
}

/**
 * @brief  event info save record 
 * @param  none
 * @return none
 * @note   none
 */
static void srv_event_saveRecord(uint8_t *pBuf, uint8_t len)
{
    uint8_t readBuf[2];
    uint32_t i = 0;	
    for (i = 0; i < EVENT_SAVE_TOTAL_SIZE; )
    {
        drv_wdg_feed();
        drv_flash_read(readBuf, i+EVENT_SAVE_START_ADDR, 2); 
		
        if ((readBuf[0] == 0xFF)&&(readBuf[1] == 0xFF))
        {
            SYSTEM_DEBUG("Event:<< write data address =0x%0x !\r\n", i+EVENT_SAVE_START_ADDR);
            drv_flash_write(pBuf, i+EVENT_SAVE_START_ADDR, len);
						/*清下一条腾出空间*/	
						if(((i+EVENT_SAVE_UNIT_SIZE+EVENT_SAVE_START_ADDR)%EVENT_SAVE_SECTOR_SIZE) == 0)
						{
								if ((i+EVENT_SAVE_UNIT_SIZE) >= EVENT_SAVE_TOTAL_SIZE)
								{
										Srv_Event_PageDelete(EVENT_SAVE_START_ADDR);
								}
								else
								{
										Srv_Event_PageDelete(i+EVENT_SAVE_UNIT_SIZE+EVENT_SAVE_START_ADDR);			
								}				
						}
						return;
        }
        i+= EVENT_SAVE_UNIT_SIZE;
    }
		/*异常清除*/
		Srv_Event_PageDelete(EVENT_SAVE_START_ADDR);
}

/**
 * @brief  event delete
 * @param  none
 * @return none
 * @note   none
 */
void srv_event_delete(void)
{
		uint32_t i = 0;	
	
    /* Unlocks the FLASH Program Erase Controller */
    FLASH_Unlock();
		for (i = 0; i < EVENT_SAVE_TOTAL_SIZE; )
		{
        /* Erase */
        if (FLASH_COMPL != FLASH_EraseOnePage(i+EVENT_SAVE_START_ADDR))
        {
            SYSTEM_DEBUG("Event:<< erase address =0x%0x error !\r\n", i+EVENT_SAVE_START_ADDR);
        }
				else
				{
						SYSTEM_DEBUG("Event:<< erase address =0x%0x success !\r\n", i+EVENT_SAVE_START_ADDR);
				}
				i+= FLASH_MAIN_SECTOR_SIZE;
				drv_wdg_feed();
		}
    /* Locks the FLASH Program Erase Controller */
    FLASH_Lock();	

}

/**
 * @brief  get event index num
 * @param  none
 * @return none
 * @note   none
 */
void srv_event_indexSearch(void)
{
    uint8_t readBuf[2];
    uint32_t i = 0;
    uint16_t index = 0;
    uint32_t address = EVENT_SAVE_START_ADDR;	
	
    for (i = 0; i < EVENT_SAVE_TOTAL_SIZE; )
    {
        drv_flash_read(readBuf, i+EVENT_SAVE_START_ADDR, 2);    
        if ((readBuf[0] != EVENT_PROTOCOL_HEAD1)&&(readBuf[1] != EVENT_PROTOCOL_HEAD2))
        {
            /*没有刷新起始地址*/
            if(i >= (EVENT_SAVE_TOTAL_SIZE - EVENT_SAVE_UNIT_SIZE))
            {
                address =   EVENT_SAVE_START_ADDR;
            }
            else
            {
                address =   i+EVENT_SAVE_START_ADDR+EVENT_SAVE_UNIT_SIZE;            
            }
        }
        else		
        {    
            index++; 
        }
        i+= EVENT_SAVE_UNIT_SIZE;
    }
	
    g_stcEvent.u32addrStart = address;
    g_stcEvent.u16index = index;
    g_stcEvent.u8timeout = EVENT_SAVE_TIMEOUT;	

}

/**
 * @brief  Event packaging storage
 * @param  none
 * @return none
 * @note   none
 */
void srv_event_save(en_event_type_t event , uint8_t cmd)
{
		uint16_t u16i = 0;
	
    if (g_stcEvent.u8timeout)/*检索中不存储*/
    {
        return;
    }

    uint8_t u8TxBuf[EVENT_SAVE_BUF_SIZE];
    uint8_t u8Count = 0;
	
    u8TxBuf[u8Count++] = EVENT_PROTOCOL_HEAD1;
    u8TxBuf[u8Count++] = EVENT_PROTOCOL_HEAD2;

    drv_rtc_getTime(&u8TxBuf[u8Count]);        
    u8Count += 6;
	
    u8TxBuf[u8Count++] = event;
    u8TxBuf[u8Count++] = (g_stcVar.u32totalSumVolt) >> 24;/*总电压 高字节 */
    u8TxBuf[u8Count++] = (g_stcVar.u32totalSumVolt) >> 16;/*总电压低字节 */
    u8TxBuf[u8Count++] = (g_stcVar.u32totalSumVolt) >> 8;/*总电压 高字节 */
    u8TxBuf[u8Count++] = (g_stcVar.u32totalSumVolt) >> 0;/*总电压低字节 */  
    u8TxBuf[u8Count++] = (g_stcVar.i32avgCurrent+1000000) >> 24;/*总电流 高字节 */
    u8TxBuf[u8Count++] = (g_stcVar.i32avgCurrent+1000000) >> 16;/*总电流低字节 */
    u8TxBuf[u8Count++] = (g_stcVar.i32avgCurrent+1000000) >> 8;/*总电流 高字节 */
    u8TxBuf[u8Count++] = (g_stcVar.i32avgCurrent+1000000) >> 0;/*总电流低字节 */
    u8TxBuf[u8Count++] = (g_stcSoc.stcdata.u32displayValue/10000);/*显示SOC低字节 */
    u8TxBuf[u8Count++] = g_stcParm.stcConfig.u8soh ;/*SOH低字节 */
		
		for (u16i = 0; u16i < BMS_MAX_CELLNUM; u16i++)
		{
				u8TxBuf[u8Count++] = g_stcVar.u16cellVolt[u16i] >> 8;
				u8TxBuf[u8Count++] = g_stcVar.u16cellVolt[u16i];
		}
		for (u16i = 0; u16i < BMS_MAX_TEMPNUM; u16i++)
		{
        u8TxBuf[u8Count++] = g_stcVar.i8cellTemp[u16i]+TEMP_OFFSET;
		}

    u8TxBuf[u8Count++] = g_stcVar.i8chgMosTemp + TEMP_OFFSET;/*充电MOS温度低字节 */	
    u8TxBuf[u8Count++] = g_stcVar.i8disMosTemp + TEMP_OFFSET;/*放电MOS温度低字节 */
    u8TxBuf[u8Count++] = g_stcVar.i8ambTemp + TEMP_OFFSET;/*环境温度低字节 */
 
    u8TxBuf[u8Count++] = g_stcVar.unProtRank2.dword >> 24;/*故障状态高字节 */
    u8TxBuf[u8Count++] = g_stcVar.unProtRank2.dword >> 16;
    u8TxBuf[u8Count++] = g_stcVar.unProtRank2.dword >> 8;
    u8TxBuf[u8Count++] = g_stcVar.unProtRank2.dword;			

    if (false == srv_contactor_getState(CNT_CHG))
    {
        u8TxBuf[u8Count++] = 0x00;	        
    }
    else
    {
        u8TxBuf[u8Count++] = 0x01;       
    }		
    if (false == srv_contactor_getState(CNT_DSG))
    {
        u8TxBuf[u8Count++] = 0x00;	        
    }
    else
    {
        u8TxBuf[u8Count++] = 0x01;       
    }
    if (false == srv_contactor_getState(CNT_PCHG))
    {
        u8TxBuf[u8Count++] = 0x00;	        
    }
    else
    {
        u8TxBuf[u8Count++] = 0x01;       
    }
    if (false == srv_contactor_getState(CNT_PDSG))
    {
        u8TxBuf[u8Count++] = 0x00;	        
    }
    else
    {
        u8TxBuf[u8Count++] = 0x01;       
    }	
    u8TxBuf[u8Count++] = 0x00;/*限流MOS低字节*/	

    u8TxBuf[u8Count++] = cmd;			/*控制命令*/	

    u8TxBuf[u8Count++] = 0x00;			/*备份1*/
    u8TxBuf[u8Count++] = 0x00;			/*备份2*/
    u8TxBuf[u8Count++] = 0x00;			/*备份3*/	
    u8TxBuf[u8Count++] = 0x00;			/*备份4*/
    u8TxBuf[u8Count++] = 0x00;			/*备份5*/
    u8TxBuf[u8Count++] = 0x00;			/*备份6*/	

    srv_event_saveRecord(u8TxBuf, u8Count);
	
}

/**
 * @brief  the event timeout deal with
 * @param  none
 * @return none
 * @note   none
 */
void srv_event_timeout(void)
{
    static uint32_t  s_u32ProtStat = 0;
    static uint32_t  s_u32WarnStat = 0;	
    if (g_stcEvent.u8timeout)
    {
        g_stcEvent.u8timeout--;
    }
	
    if (g_stcVar.unProtRank2.dword!= s_u32ProtStat)
    {
        /*更新当前数据状态*/
				app_afe_readAllRam();
        s_u32ProtStat = g_stcVar.unProtRank2.dword;
        srv_event_save(EVENT_TYPE_ALARM , 0);	
    }
    if (g_stcVar.unProtRank1.dword!= s_u32WarnStat)
    {
        /*更新当前数据状态*/
				app_afe_readAllRam();
        s_u32WarnStat = g_stcVar.unProtRank1.dword;
        srv_event_save(EVENT_TYPE_ALARM , 1);	
    }

}

/**
 * @brief  the event init
 * @param  none
 * @return none
 * @note   none
 */
void srv_event_init(void)
{
    memset(&g_stcEvent,0x00,sizeof(stc_event_t));		
}

// =======================================================================================
// End of file.
// =======================================================================================
